

#include "lmexxx_conf.h"

#define GSMC_SIZE						16

typedef struct{
	uint8_t* msg;
	uint16_t msg_len;
	uint16_t delay_time_tick;
	uint16_t blocking_time_tick;
	uint16_t matching_time_tick;
	uint8_t max_repeat;
}GSMC_STRUCT;

static GSMC_STRUCT gsmc_buff[GSMC_SIZE];

static uint8_t gsmc_buff_search(uint8_t* target_msg)
{
	for(uint8_t i = 0; i < GSMC_SIZE; i++){
		if(target_msg == gsmc_buff[i].msg){
			return i;
		}
	}
	return 0xff;
}

uint8_t matching_ack_init(void);
uint8_t matching_ack_match(uint8_t* msg, uint16_t msg_len, uint16_t wait_time_tick);
uint8_t matching_ack_rec(uint8_t* rec_msg, uint16_t rec_msg_len);

uint8_t blocking_send_init(void);
uint8_t blocking_send_send(uint8_t* msg, uint16_t msg_len, uint16_t interval_time);

uint8_t delay_send_init(void);
uint8_t delay_send_send(uint8_t* msg, uint16_t msg_len, uint16_t delay_time_tick);

uint8_t gsmc_send(uint8_t *msg, uint16_t msg_len, 
					uint16_t delay_time_tick,
					uint16_t blocking_time_tick,
					uint16_t matching_time_tick,
					uint8_t max_repeat)
{
	uint8_t *buf;

	for(uint8_t i = 0; i < GSMC_SIZE; i++){
		if(NULL == gsmc_buff[i].msg){
			buf = (uint8_t*)pvPortMalloc(msg_len);
			if(buf == NULL){
				return 0;
			}
			memcpy(buf, msg, msg_len);
			gsmc_buff[i].msg = buf;
			gsmc_buff[i].msg_len = msg_len;
			gsmc_buff[i].delay_time_tick = delay_time_tick;
			gsmc_buff[i].blocking_time_tick = blocking_time_tick;
			gsmc_buff[i].matching_time_tick = matching_time_tick;
			gsmc_buff[i].max_repeat = max_repeat;

			delay_send_send(gsmc_buff[i].msg, gsmc_buff[i].msg_len, gsmc_buff[i].delay_time_tick);

			return 1;
		}
	}
	return 0;
}

uint8_t gsmc_match(uint8_t* rec_msg, uint16_t rec_msg_len)
{
	return matching_ack_rec(rec_msg, rec_msg_len);
}

uint8_t gsmc_init(void)
{
	if(0 == delay_send_init())
	{
		return 0;
	}
	if(0 == blocking_send_init())
	{
		return 0;
	}
	if(0 == matching_ack_init())
	{
		return 0;
	}

	for(uint8_t i = 0; i < GSMC_SIZE; i++){
		gsmc_buff[i].msg = NULL;
	}
	return 1;
}

/**************************************************************************/
extern void gsmc_send_hook(uint8_t *msg, uint16_t msg_len);
extern void gsmc_timeout_hook(uint8_t *msg, uint16_t msg_len);
extern uint8_t gsmc_match_hook(uint8_t* rec_msg, uint16_t rec_msg_len, 
								uint8_t* match_msg, uint16_t match_msg_len);

void matching_ack_timeout_hook(uint8_t* match_msg, uint16_t msg_len)
{
	// LOGINFO0(UART_DEBUG, "-----------------------\ntime out\n");
	// printData(match_msg, msg_len);

	uint8_t index;
	index = gsmc_buff_search(match_msg);
	if(index != 0xff){
		if(gsmc_buff[index].max_repeat > 0){	//repeat
			// LOGINFO0(UART_DEBUG, "----------------------- repeat\n");
			delay_send_send(gsmc_buff[index].msg, gsmc_buff[index].msg_len, 0);
			gsmc_buff[index].max_repeat--;
		}
		else{
			gsmc_timeout_hook(match_msg, msg_len);
			vPortFree(match_msg);
			gsmc_buff[index].msg = NULL;
		}
	}
}

uint8_t matching_ack_rec_hook(uint8_t* rec_msg, uint16_t rec_msg_len, 
								uint8_t* match_msg, uint16_t match_msg_len)
{
	uint8_t index;
	index = gsmc_buff_search(match_msg);
	if(index == 0xff){
		return 0;
	}
	if(1 == gsmc_match_hook(rec_msg, rec_msg_len, match_msg, match_msg_len)){

		// LOGINFO0(UART_DEBUG, "-----------------------\nmatch ok\n");
		// printData(rec_msg, rec_msg_len);

		vPortFree(gsmc_buff[index].msg);
		gsmc_buff[index].msg = NULL;
		return 1;
	}
	else{
		return 0;
	}
}

void blocking_send_send_hook(U8* msg, U16 msg_len)
{
	uint8_t index;
	index = gsmc_buff_search(msg);
	if(index != 0xff){

		// LOGINFO0(UART_DEBUG, "-----------------------\nblocking_send_send_hook\n");
		// printData(msg, msg_len);

		gsmc_send_hook(gsmc_buff[index].msg, gsmc_buff[index].msg_len);
		if(gsmc_buff[index].matching_time_tick > 0){
			matching_ack_match(gsmc_buff[index].msg, gsmc_buff[index].msg_len, gsmc_buff[index].matching_time_tick);
		}
	}
}

void delay_send_send_hook(uint8_t* msg, uint16_t msg_len)
{
	uint8_t index;
	index = gsmc_buff_search(msg);
	if(index != 0xff){

		// LOGINFO0(UART_DEBUG, "-----------------------\ndelay_send_send_hook\n");
		// printData(msg, msg_len);

		blocking_send_send(gsmc_buff[index].msg, gsmc_buff[index].msg_len, gsmc_buff[index].blocking_time_tick);
	}
}


//e.g.
// uint8_t gsmc_init(void);
// uint8_t gsmc_match(uint8_t* rec_msg, uint16_t rec_msg_len);
// uint8_t gsmc_send(uint8_t *msg, uint16_t msg_len, 
// 					uint16_t delay_time_tick,
// 					uint16_t blocking_time_tick,
// 					uint16_t matching_time_tick,
// 					uint8_t max_repeat);

// void gsmc_send_hook(uint8_t *msg, uint16_t msg_len)
// {
// 	Uart_SendData(UART_COM1, msg, msg_len);
// }

// void gsmc_timeout_hook(uint8_t *msg, uint16_t msg_len)
// {
// }

// uint8_t gsmc_match_hook(uint8_t* rec_msg, uint16_t rec_msg_len, 
// 								uint8_t* match_msg, uint16_t match_msg_len)
// {
// 	if(memcmp(rec_msg, match_msg, match_msg_len) == 0)
// 	{
// 		return 1;	
// 	}
// 	else
// 	{
// 		return 0;
// 	}
// }



